"""
错误处理工具
提供错误上下文管理器和安全执行函数
"""
import logging
from contextlib import contextmanager
from typing import Optional, Type, Any, Callable, TypeVar, cast

from .mapping import map_error_from_provider
from ...core.exceptions import LLMException

# 设置日志
logger = logging.getLogger("connllm.errors")

# 定义泛型返回类型
T = TypeVar('T')

@contextmanager
def error_context(provider_type: str, model: Optional[str] = None, operation: Optional[str] = None):
	"""
	错误处理上下文管理器
	简化错误处理和转换
	
	Args:
		provider_type: 提供商类型
		model: 模型名称
		operation: 操作名称，用于日志记录
		
	Yields:
		上下文
		
	Raises:
		LLMException: 映射后的LLM异常
	"""
	try:
		yield
	except Exception as e:
		# 已经是LLM异常的直接抛出
		if isinstance(e, LLMException):
			if operation:
				logger.error(f"操作 {operation} 失败: {str(e)}")
			raise
			
		# 否则映射为标准LLM异常
		error = map_error_from_provider(provider_type, e, model)
		if operation:
			logger.error(f"操作 {operation} 失败: {str(error)}")
		raise error from e

def safe_execute(
	func: Callable[..., T], 
	provider_type: str, 
	model: Optional[str] = None,
	default: Any = None,
	log_error: bool = True,
	operation: Optional[str] = None,
	*args, **kwargs
) -> T:
	"""
	安全执行函数，出错时返回默认值
	
	Args:
		func: 要执行的函数
		provider_type: 提供商类型
		model: 模型名称
		default: 出错时返回的默认值
		log_error: 是否记录错误日志
		operation: 操作名称，用于日志记录
		*args: 函数位置参数
		**kwargs: 函数关键字参数
		
	Returns:
		函数返回值或默认值
	"""
	try:
		return func(*args, **kwargs)
	except Exception as e:
		# 映射错误并记录日志
		if log_error:
			error = e
			if not isinstance(e, LLMException):
				error = map_error_from_provider(provider_type, e, model)
				
			if operation:
				logger.error(f"操作 {operation} 失败: {str(error)}")
			else:
				logger.error(f"函数执行失败: {str(error)}")
				
		# 返回默认值
		return cast(T, default)
